package com.yc.common.utils;

/**
 * @Author 写你的名字
 * @Date 2023/7/26 9:56 （可以根据需要修改）
 * @Version 1.0 （版本号）
 */

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import com.yc.mapper.AttendanceMapper;
import com.yc.service.AttendanceService;
import com.yc.service.impl.AttendanceServiceImpl;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpsUtils {
    private static AttendanceService attendanceService = new AttendanceServiceImpl();
    private static Logger logger = LoggerFactory.getLogger(HttpsUtils.class);
    static CloseableHttpClient httpClient;
    static CloseableHttpResponse httpResponse;

    public static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();

    }

    /**
     * 发送https请求
     *
     * @throws Exception
     */
    public static String sendByHttp(Map<String, Object> params, String url) {
        try {
            HttpPost httpPost = new HttpPost(url);
            List<NameValuePair> listNVP = new ArrayList<NameValuePair>();
            if (params != null) {
                for (String key : params.keySet()) {
                    listNVP.add(new BasicNameValuePair(key, params.get(key).toString()));
                }
            }
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(listNVP, "UTF-8");
            logger.info("创建请求httpPost-URL={},params={}", url, listNVP);
            httpPost.setEntity(entity);
            httpClient = HttpsUtils.createSSLClientDefault();
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                String jsObject = EntityUtils.toString(httpEntity, "UTF-8");
                return jsObject;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                httpResponse.close();
                httpClient.close();
                logger.info("请求流关闭完成");
            } catch (IOException e) {
                logger.info("请求流关闭出错");
                e.printStackTrace();
            }
        }
    }

    public static String test(String url){
        String s = HttpsUtils.sendByHttp(null, url);
        Document doc = Jsoup.parse(s);
        Element hrefBox = doc.selectFirst(".list_box_noticess li:first-child a");
        String href = hrefBox.attr("href");
        return "https://www.hnit.edu.cn"+href.substring(2);
    }
    public static List<String> demo(String url) {
        String s = HttpsUtils.sendByHttp(null, url);
        Document doc = Jsoup.parse(s);
        Elements tables = doc.select("table");

        //一共两个表格
        if (!tables.isEmpty()) {
            //先得到每个表格对应的学年
            //上面的日期往后推移，每七天一个周次
            Elements spanTagsWithCustomStyle =
                    doc.select("span[style=\"font-family: 方正小标宋简体; font-size: 19px;\"]");
            spanTagsWithCustomStyle.remove(1);
            List<String> dd = new ArrayList<>();
            for (int i = 0; i < 2; i++) {
                //学年
                String title = spanTagsWithCustomStyle.get(i).text();
                //表格
                Element table = tables.get(i);
                String regex = "\\d{4}-\\d{4}-\\d{1}";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(title);
                if (matcher.find()) {
                    String schoolYear = matcher.group();
                    Elements rows = table.select("tr");
                    String beginDay = rows.get(1).text().split(" ")[5];
                    regex = "\\d+月\\d+日";

                    pattern = Pattern.compile(regex);
                    matcher = pattern.matcher(beginDay);

                    if (matcher.find()) {
                        String[] strings = matcher.group().substring(0, matcher.group().length() - 1).split("月");
                        for (String string : strings) {
                            System.out.println(string);
                        }
                        beginDay = (strings[0].length() == 1 ? "0" + strings[0] : strings[0])
                                + "-" +
                                (strings[1].length() == 1 ? "0" + strings[1] : strings[1]);
                        //进到这里就代表都查询到了
                        //从开始的那一天开始每一周加入对应的学期当中
                        String begin = (i == 0 ? schoolYear.split("-")[0] : schoolYear.split("-")[1]) + "-" + beginDay;

                        dd.add(schoolYear + " " + begin);
                    }
                }
            }
            return dd;

        } else {
            System.out.println("No table found.");
        }
        return null;
    }

    public static List<String> getNext20WeeksMondays(String inputDate) {
        List<String> mondaysList = new ArrayList<>();

        // 解析输入的日期字符串为 LocalDate 对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(inputDate, formatter);

        // 如果当前日期不是星期一，找到下一个星期一
        while (date.getDayOfWeek() != DayOfWeek.MONDAY) {
            date = date.plusDays(-1);
        }

        // 先添加给定日期所处的周一到结果列表
        mondaysList.add(date.format(formatter));

        // 计算之后20个周的星期一的时间
        for (int i = 0; i < 20; i++) {
            // 增加一周的时间（7天）
            date = date.plusDays(7);
            // 将当前日期加入结果列表
            mondaysList.add(date.format(formatter));
        }

        return mondaysList;
    }

    public static List<String> getOtherDatesInSameWeek(String inputDate) {
        List<String> d = new ArrayList<>();
        // 解析输入的日期字符串为 LocalDate 对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(inputDate, formatter);

        // 找到所在周的第一天（周一）
        LocalDate firstDayOfWeek = date;
        while (firstDayOfWeek.getDayOfWeek() != DayOfWeek.MONDAY) {
            firstDayOfWeek = firstDayOfWeek.minusDays(1);
        }

        Map<String,String> map = new HashMap<>();
        // 获取其他日期
        int j = 1;
        for (int i = 0; i < 7; i++) {
            LocalDate otherDate = firstDayOfWeek.plusDays(i);
            map.put(otherDate.format(formatter),"星期"+ j++);
            d.add(otherDate.format(formatter));
        }

        return d;
    }

    /**
    *@Description 日期转换为星期
    *@Return
    *@Author dm
    *@Date Created in 2023/8/3 14:09
    **/
    public static String dateToWeek(String datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        try {
            datet = f.parse(datetime);
            cal.setTime(datet);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }
}
